package org.lalib.controller.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.model.SelectItem;

import org.lalib.acquire.IControllerService;
import org.lalib.controller.form.CVariableForm.VariableDefination;
import org.lalib.entity.object.ECategory;
import org.lalib.entity.object.variable.BigDecimalVariable;
import org.lalib.entity.object.variable.DateVariable;
import org.lalib.entity.object.variable.DropDownListVariable;
import org.lalib.entity.object.variable.EnumVariable;
import org.lalib.entity.object.variable.ListVariable;
import org.lalib.entity.object.variable.StringVariable;
import org.lalib.entity.object.variable.EVariable;
import org.lalib.mediator.MVariable;
import org.lalib.util.VariableTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service(value = "cVariableService")
@Scope(value = "prototype")
public class CVariableService implements IControllerService {

	private static final long serialVersionUID = 1L;
	@Autowired
	private MVariable mVariable;

	public EVariable getVariableById(Long id) {
		return mVariable.getEntityById(id);
	}

	public List<EVariable> getVariablesForGivenCategory(ECategory eCategory) {
		return mVariable.getVariablesForGivenCategory(eCategory);
	}

	public void delete(EVariable eVariable) {
		eVariable = mVariable.getEntityById(eVariable.getId());
		mVariable.remove(eVariable);
	}

	public void saveNewVariable(VariableDefination variableDefination, ECategory category) {
		String variableName = variableDefination.getName();
		if (isVariableExist(variableName))
			return;

		EVariable variable = getNewVariableInstanceFromGivenVariableType(variableDefination.getType());
		variable.setCategory(category);
		variable.setDescription(variableDefination.getDescription());
		variable.setLabel(variableDefination.getLabel());
		variable.setName(variableDefination.getName());
		variable.setRequired(variableDefination.isRequired());
		variable.setTabName(variableDefination.getTabName());
		mVariable.insert(variable);
	}

	public void update(EVariable variable) {
		mVariable.update(variable);
	}

	public Map<String, String> getVariableMap() {
		Map<String, String> variableMap = new HashMap<>();
		variableMap.put("B", VariableTypes.BIGDECIMALVARIABLE);
		variableMap.put("D", VariableTypes.DATEVARIABLE);
		variableMap.put("DL", VariableTypes.DROPDOWNLISTVARIABLE);
		variableMap.put("E", VariableTypes.ENUMVARIABLE);
		variableMap.put("L", VariableTypes.LISTVARIABLE);
		variableMap.put("S", VariableTypes.STRINGVARIABLE);
		return variableMap;
	}

	public boolean isVariableExist(String variableName) {
		return mVariable.isVariableExist(variableName);
	}

	public List<SelectItem> getVariableSelectItemListFromVariableMap(Map<String, String> variableMap) {
		List<SelectItem> variableSelectItemList = new ArrayList<>();
		for (Map.Entry<String, String> entry : variableMap.entrySet())
			variableSelectItemList.add(new SelectItem(entry.getKey(), entry.getValue()));
		return variableSelectItemList;
	}

	public List<EVariable> getAllVariablesForGivenCategoryList(List<ECategory> categoryList) {
		List<EVariable> variableList = new ArrayList<EVariable>();
		for (ECategory category : categoryList)
			for (EVariable variable : category.getVariableList())
				variableList.add(variable);
		return variableList;
	}

	public EVariable getNewVariableInstanceFromGivenVariableType(String variableType) {
		if (variableType.equals("S"))
			return new StringVariable();
		else if (variableType.equals("B"))
			return new BigDecimalVariable();
		else if (variableType.equals("D"))
			return new DateVariable();
		else if (variableType.equals("E"))
			return new EnumVariable();
		else if (variableType.equals("L"))
			return new ListVariable();
		else if (variableType.equals("DL")) {
			return new DropDownListVariable();
		}
		return null;
	}

	public List<String> getUniqueTabNamesForGivenVariables(List<ECategory> categories) {
		return mVariable.getUniqueTabNamesForGivenVariables(categories);
	}

	public List<EVariable> getVariables(String tabname) {
		return mVariable.getVariablesForTabname(tabname);
	}

	public EVariable getVariableByName(String variableName) {
		return mVariable.getVariableByName(variableName);
	}
}